home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / bin / ginsu / clip.C < prev    next >
C/C++ Source or Header  |  1992-11-17  |  13KB  |  582 lines

  1. #include "clip.h"
  2.  
  3. /* Clipper 1.0 */
  4. /* by Daeron */
  5.  
  6. /*****************************************************************************/
  7.  
  8. void err_msg(char *errmsg)
  9. {
  10.  fprintf(stderr,"%s\n",errmsg);
  11.  exit(1);
  12. }
  13.  
  14. /*****************************************************************************/
  15.  
  16. /* Class initializers */
  17.  
  18. vertex::vertex()
  19. {
  20.  x=0;y=0;z=0;clip=0;vr=0.0;vg=0.0;vb=0.0;num=0;next=NULL;
  21. }
  22.  
  23. vertex_list::vertex_list()
  24. {
  25.  numvtx=0;head=NULL;ptype=0;
  26. }
  27.  
  28. pvtx::pvtx()
  29. {
  30.  num=0;next=NULL;
  31. }
  32.  
  33. polyvtx_list::polyvtx_list()
  34. {
  35.  numvtx=0;head=NULL;
  36. }
  37.  
  38. poly::poly()
  39. {
  40.  numvtx=0;me=NULL;next=NULL;clipped=0;
  41. }
  42.  
  43. poly_list::poly_list()
  44. {
  45.  numpoly=0;head=NULL;ptype=0;
  46. }
  47.  
  48. /*****************************************************************************/
  49.  
  50. void vertex_list::clip_vertex(int argc,char *argv[])
  51. {
  52.  double tmp,tmp2;
  53.  
  54.  if (!strcmp(argv[3],"-g")) side=1;
  55.  else if (!strcmp(argv[3],"-l")) side=0;
  56.  else err_msg("Usage: clip <filename> <outfile> -[gl] #a #b #c #d");
  57.  sscanf(argv[4],"%lf",&a);
  58.  sscanf(argv[5],"%lf",&b);
  59.  sscanf(argv[6],"%lf",&c);
  60.  sscanf(argv[7],"%lf",&d);
  61.  point = head;
  62.  while (point!=NULL)
  63.  {
  64.   tmp = a*(point->x) + b*(point->y) + c*(point->z);
  65.   tmp2 = tmp-d;
  66.   if (tmp2<0) tmp2*=(-1.0);
  67.   if (tmp2>.00001)
  68.   {
  69.    if ((tmp<d)&&(side==1))
  70.     point->clip=1;
  71.    else
  72.    if ((tmp>d)&&(side==0))
  73.     point->clip=1;
  74.   }
  75.   point = point->next;
  76.  }
  77. }
  78.  
  79. /*****************************************************************************/
  80.  
  81. void vertex_list::put_in_array(vertex **vertex_set)
  82. {
  83.   int count=0;
  84.  
  85.   point = head;
  86.   while (point!=NULL)
  87.   {
  88.    vertex_set[count] = point;
  89.    point=point->next;
  90.    count++;
  91.   }
  92. }
  93.  
  94. /*****************************************************************************/
  95.  
  96. vertex *vertex_list::add_vertex(double x, double y, double z, float vr, float vg, float vb)
  97. {
  98.   vertex *temp = head;
  99.  
  100.   head = new vertex;
  101.   head->next = temp;
  102.   head->x = x; head->y = y; head->z = z;
  103.   head->vr = vr; head->vg = vg; head->vb = vb;
  104.   head->clip = 0;
  105.   return (head);
  106. }
  107.  
  108. /*****************************************************************************/
  109.  
  110. int polyvtx_list::find_unclipped_vertex(vertex **vertex_set)
  111. {
  112.  pvtx *temp = head;
  113.  int brk=0;
  114.  
  115.  point = head;
  116.  do
  117.  {
  118.   brk = vertex_set[point->num]->clip;
  119.   if (brk)
  120.    point=point->next;
  121.  } while ((brk)&&(point!=temp));
  122.  if ((point==temp)&&(brk)) return (1);
  123.  head = point;
  124.  return (0);
  125. }
  126.  
  127. /*****************************************************************************/
  128.  
  129. int polyvtx_list::clip_each_vertex(vertex_list *vtxl, vertex **vertex_set)
  130. {
  131.  pvtx *temp, *next, *last;
  132.  double t,t1,t2,nx,ny,nz;
  133.  double x1,y1,z1;
  134.  double x2,y2,z2;
  135.  float vr1,vg1,vb1;
  136.  float vr2,vg2,vb2;
  137.  float vr,vg,vb;
  138.  
  139.  double a = vtxl->a, b = vtxl->b, c = vtxl->c, d = vtxl->d;
  140.  last = head;
  141.  point = head;
  142.  //fprintf(stderr,"point: %d\n",point);
  143.  point->me = vertex_set[point->num];
  144.  //fprintf(stderr,"got here\n");
  145.  do 
  146.  {
  147.   next = point->next;
  148.   next->me = vertex_set[next->num];
  149.   vr1 = vertex_set[point->num]->vr; vg1 = vertex_set[point->num]->vg;
  150.   vb1 = vertex_set[point->num]->vb;
  151.   vr2 = vertex_set[next->num]->vr; vg2 = vertex_set[next->num]->vg;
  152.   vb2 = vertex_set[next->num]->vb;
  153.   x1 = vertex_set[point->num]->x; y1 = vertex_set[point->num]->y;
  154.   z1 = vertex_set[point->num]->z;
  155.   x2 = vertex_set[next->num]->x; y2 = vertex_set[next->num]->y;
  156.   z2 = vertex_set[next->num]->z;
  157.   if ((!(vertex_set[point->num]->clip))&&(vertex_set[next->num]->clip))
  158.   {
  159.    t1 = (d - a*x1 - b*y1 - c*z1);
  160.    t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1);
  161.    if (t2!=0.0)
  162.    {
  163.     t = t1 / t2;
  164.     nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
  165.     vr = vr1 + t*(vr2 - vr1); vg = vg1 + t*(vg2 - vg1); vb = vb1 + t*(vb2 - vb1);
  166.     temp = new pvtx;
  167.     temp->me = vtxl->add_vertex(nx,ny,nz,vr,vg,vb);
  168.     numvtx++;
  169.     temp->next = next;
  170.     point->next = temp;
  171.     last = temp;
  172.     point = next;
  173.     next = point->next;
  174.    }
  175.    else
  176.    {
  177.     last = point;
  178.     point = next;
  179.     next = point->next;
  180.     vertex_set[point->num]->clip = 0;
  181.    }
  182.   }
  183.   else if ((vertex_set[point->num]->clip)&&(vertex_set[next->num]->clip))
  184.   {
  185.    /*t2 = a*(x2-x1) + b*(y2-y1) + c*(z2-z1);
  186.    if (t2!=0.0)
  187.    {*/
  188.     last->next = next;
  189.     delete point;
  190.     numvtx--;
  191.     point = next;
  192.     next = point->next;
  193.    /*}
  194.    else
  195.    {
  196.     printf("AAAA!\n");
  197.     last = point;
  198.     point = next;
  199.     next = point->next;
  200.    }*/
  201.   }
  202.   else if ((vertex_set[point->num]->clip)&&(!(vertex_set[next->num]->clip)))
  203.   {
  204.    t1 = (d - a*x1 - b*y1 - c*z1);
  205.    t2 = a*(x2 - x1) + b*(y2 - y1) + c*(z2 - z1);
  206.    if (t2!=0.0)
  207.    {
  208.     t = t1/t2;
  209.     nx = x1 + t*(x2 - x1); ny = y1 + t*(y2 - y1); nz = z1 + t*(z2 - z1);
  210.     vr = vr1 + t*(vr2 - vr1); vg = vg1 + t*(vg2 - vg1); vb = vb1 + t*(vb2 - vb1);
  211.     temp = new pvtx;
  212.     temp->me = vtxl->add_vertex(nx,ny,nz,vr,vg,vb);
  213.     temp->next = next;
  214.     last->next = temp;
  215.     delete point;
  216.     last = temp;
  217.     point = next;
  218.     next = point->next;
  219.    }
  220.    else
  221.    {
  222.     last = point;
  223.     vertex_set[point->num]->clip = 0;
  224.     point = next;
  225.     next = point->next;
  226.    }
  227.   }
  228.   else
  229.   {
  230.    last=point;
  231.    point=next;
  232.    next=point->next;
  233.   }
  234.  } while (point!=head);
  235.  return numvtx;
  236. }
  237.  
  238. /*****************************************************************************/
  239.  
  240. void poly::clip_poly(vertex_list *vtxl, vertex **vertex_set)
  241. {
  242.  
  243.   clipped = me->find_unclipped_vertex(vertex_set);
  244.   if (clipped) return;
  245.   numvtx = me->clip_each_vertex(vtxl,vertex_set);
  246. }
  247.  
  248. /*****************************************************************************/
  249.  
  250. void poly_list::clip_polys(vertex_list *vtxl)
  251. {
  252.  
  253.  vertex **vertex_set;
  254.  
  255.  vertex_set = new vertex*[vtxl->numvtx];
  256.  vtxl->put_in_array(vertex_set);
  257.  point = head;
  258.  while (point!=NULL)
  259.  {
  260.   point->clip_poly(vtxl,vertex_set);
  261.   point=point->next;
  262.  }
  263. }
  264.  
  265. /*****************************************************************************/
  266.  
  267. void vertex::read_vertex(int count, FILE *fin)
  268. {
  269.  char c;
  270.  fscanf(fin,"%lf %lf %lf",&x,&y,&z);
  271.  //fprintf(stderr,"%lf %lf %lf\n",x,y,z);
  272.  vr=1.0;vg=1.0;vb=1.0;
  273.  c = ' ';
  274.  while (!feof(fin) && c!='\n')
  275.   c = (char)fgetc(fin);
  276.  num=count;
  277. }
  278.  
  279. /*****************************************************************************/
  280.  
  281. void vertex::read_cvertex(int count, FILE *fin)
  282. {
  283.  char c;
  284.  fscanf(fin,"%lf %lf %lf %f %f %f",&x,&y,&z,&vr,&vg,&vb);
  285.  if (vr>1.0) vr/=255.0;
  286.  if (vg>1.0) vg/=255.0;
  287.  if (vb>1.0) vb/=255.0;
  288.  if ((vr<0.0)||(vr>1.0)) vr=0.0;
  289.  if ((vg<0.0)||(vg>1.0)) vg=0.0;
  290.  if ((vb<0.0)||(vb>1.0)) vb=0.0;
  291.  //fprintf(stderr,"%lf %lf %lf\n",x,y,z);
  292.  c = ' ';
  293.  while (!feof(fin) && c!='\n')
  294.   c = (char)fgetc(fin);
  295.  num=count;
  296. }
  297.  
  298. /*****************************************************************************/
  299.  
  300. void vertex::read_cnvertex(int count, FILE *fin)
  301. {
  302.  char c;
  303.  float dm;
  304.  fscanf(fin,"%lf %lf %lf %f %f %f %f %f %f",&x,&y,&z,&dm,&dm,&dm,&vr,&vg,&vb);
  305.  if (vr>1.0) vr/=255.0;
  306.  if (vg>1.0) vg/=255.0;
  307.  if (vb>1.0) vb/=255.0;
  308.  if ((vr<0.0)||(vr>1.0)) vr=0.0;
  309.  if ((vg<0.0)||(vg>1.0)) vg=0.0;
  310.  if ((vb<0.0)||(vb>1.0)) vb=0.0;
  311.  //fprintf(stderr,"%lf %lf %lf\n",x,y,z);
  312.  c = ' ';
  313.  while (!feof(fin) && c!='\n')
  314.   c = (char)fgetc(fin);
  315.  num=count;
  316. }
  317.  
  318. /*****************************************************************************/
  319.  
  320. void vertex_list::read_vertices(int numvx, FILE *fin)
  321. {
  322.  int count;
  323.  vertex *old;
  324.  
  325.  numvtx = numvx;
  326.  point = new vertex;
  327.   if (ptype==0)
  328.    point->read_vertex(0,fin);
  329.   else if (ptype==1)
  330.    point->read_cvertex(0,fin);
  331.   else if (ptype==2)
  332.    point->read_cnvertex(0,fin);
  333.  head = point;
  334.  old = point;
  335.  for (count=1;count<numvtx;count++)
  336.  {
  337.   point = new vertex;
  338.   old->next = point;
  339.   if (ptype==0)
  340.    point->read_vertex(count,fin);
  341.   else if (ptype==1)
  342.    point->read_cvertex(count,fin);
  343.   else if (ptype==2)
  344.    point->read_cnvertex(count,fin);
  345.   old = point;
  346.  }
  347.  point->next = NULL;
  348. }
  349.  
  350. /*****************************************************************************/
  351.  
  352. void pvtx::read_pvtx(FILE *fin)
  353. {
  354.  fscanf(fin," %d",&num);
  355.  //fprintf(stderr," %d",num);
  356. }
  357.  
  358. /*****************************************************************************/
  359.  
  360. void polyvtx_list::read_polyvtx(int numvx, FILE *fin)
  361. {
  362.  int count;
  363.  pvtx *old;
  364.  //char temp;
  365.  
  366.  numvtx = numvx;
  367.  point = new pvtx;
  368.  point->read_pvtx(fin);
  369.  head = point;
  370.  old = point;
  371.  for (count=1;count<numvtx;count++)
  372.  {
  373.   point = new pvtx;
  374.   old->next = point;
  375.   point->read_pvtx(fin);
  376.   old = point;
  377.  }
  378.  point->next = head;
  379. }
  380.  
  381. /*****************************************************************************/
  382.  
  383. void poly::read_poly(FILE *fin)
  384. {
  385.  char temp;
  386.  fscanf(fin,"%d",&numvtx);
  387.  //fprintf(stderr,"%d",numvtx);
  388.  me = new polyvtx_list;
  389.  me->read_polyvtx(numvtx,fin);
  390.  r=1.0;g=1.0;b=1.0;
  391.  fscanf(fin,"%c",&temp);
  392.  if (temp!='\n')
  393.  {
  394.   fscanf(fin,"%f %f %f",&r,&g,&b);
  395.   fscanf(fin,"%c",&temp);
  396.   while ((temp!='\n')&&(!feof(fin)))
  397.    fscanf(fin,"%c",&temp);
  398.  }
  399. }
  400.  
  401.  
  402. /*****************************************************************************/
  403.  
  404. void poly_list::read_polys(int numpl, FILE *fin)
  405. {
  406.  int count;
  407.  poly *old;
  408.  
  409.  numpoly = numpl;
  410.  point = new poly;
  411.  point->read_poly(fin);
  412.  head = point;
  413.  old = point;
  414.  for (count=1;count<numpoly;count++)
  415.  {
  416.   point = new poly;
  417.   old->next = point;
  418.   point->read_poly(fin);
  419.   old = point;
  420.  }
  421.  point->next = NULL;
  422. }
  423.  
  424. /*****************************************************************************/
  425.  
  426. void vertex_list::refresh_vertex_list()
  427. {
  428.  int count = 0;
  429.  
  430.  point = head;
  431.  while (point!=NULL)
  432.  {
  433.   if (!(point->clip))
  434.   {
  435.    point->num = count;
  436.    count++;
  437.   }
  438.   point=point->next;
  439.  }
  440.  numvtx=count;
  441. }
  442.  
  443. /*****************************************************************************/
  444.  
  445. void poly_list::refresh_poly_list()
  446. {
  447.  int count = 0;
  448.  
  449.  point = head;
  450.  while (point!=NULL)
  451.  {
  452.   if (!(point->clipped))
  453.    count++;
  454.   point=point->next;
  455.  }
  456.  numpoly=count;
  457. }
  458.  
  459. /*****************************************************************************/
  460.  
  461. void load_off_file(poly_list *polyhedron, vertex_list *polyvertex,
  462.         int argc, char *argv[], char *storename)
  463. {
  464.  FILE *fin;
  465.  char toss[256];
  466.  char c;
  467.  int vrtx,face,edge;
  468.  
  469.  if ((argc<8)||(argc>8)) err_msg("Usage: clip <filename> <outfile> -[gl] #a #b #c #d");
  470.  if (!(fin=fopen(argv[1],"r"))) err_msg("Could not open input file.");
  471.  c = ' ';
  472.  while ((c!='=')&&(!feof(fin)))
  473.   c=(char)fgetc(fin);
  474.  fscanf(fin,"%s\n",toss);
  475.  sprintf(storename,"%s",argv[2]);
  476.  if (strcmp(toss,"OFF")&&strcmp(toss,"NOFF")&&strcmp(toss,"COFF")&&strcmp(toss,"CNOFF")) err_msg("Incorrect file format");
  477.  if (!strcmp(toss,"OFF")) polyvertex->ptype=0;
  478.  else if (!strcmp(toss,"NOFF")) polyvertex->ptype=0;
  479.  else if (!strcmp(toss,"COFF")) polyvertex->ptype=1;
  480.  else if (!strcmp(toss,"CNOFF")) polyvertex->ptype=2;
  481.  polyhedron->ptype = polyvertex->ptype;
  482.  fscanf(fin,"%d %d %d\n",&vrtx,&face,&edge);
  483.  if ((vrtx==0)||(face==0)||(edge==0)) err_msg("Bad parameters.");
  484.  polyvertex->read_vertices(vrtx,fin);
  485.  polyhedron->read_polys(face,fin);
  486. }
  487.  
  488. /*****************************************************************************/
  489.  
  490. void vertex_list::write_vertices(FILE *fout)
  491. {
  492.  point=head;
  493.  if (ptype==0)
  494.  {
  495.   while(point!=NULL)
  496.   {
  497.    if (!(point->clip))
  498.     fprintf(fout,"\t%lf %lf %lf\n",point->x,point->y,point->z);
  499.    point=point->next;
  500.   }
  501.  }
  502.  else
  503.  {
  504.   while(point!=NULL)
  505.   {
  506.    if (!(point->clip))
  507.     fprintf(fout,"\t%lf %lf %lf %f %f %f 1.0\n",point->x,point->y,point->z,point->vr,point->vg,point->vb);
  508.    point=point->next;
  509.   }
  510.  }
  511. }
  512.  
  513. /*****************************************************************************/
  514.  
  515. void polyvtx_list::write_polyvtx(FILE *fout)
  516. {
  517.  pvtx *temp;
  518.  
  519.  temp=head;
  520.  point=head;
  521.  fprintf(fout,"\t%d",numvtx);
  522.  do
  523.  {
  524.   fprintf(fout," %d",point->me->num);
  525.   point=point->next;
  526.  } while (point!=temp);
  527. }
  528.  
  529. /*****************************************************************************/
  530.  
  531. void poly_list::write_polys(FILE *fout)
  532. {
  533.  point=head;
  534.  while(point!=NULL)
  535.  {
  536.   if (!(point->clipped))
  537.    {
  538.     point->me->write_polyvtx(fout);
  539.     if (ptype==0)
  540.      fprintf(fout," %f %f %f 1.0\n",point->r,point->g,point->b);
  541.     else
  542.      fprintf(fout,"\n");
  543.    }
  544.   point=point->next;
  545.  }
  546. }
  547.  
  548. /*****************************************************************************/
  549.  
  550. void store_off_file(poly_list *polyhedron, vertex_list *polyvertex,
  551.         char *storename)
  552. {
  553.  FILE *fout;
  554.  
  555.  if (!(fout=fopen(storename,"w"))) err_msg("Couldn\'t save to output file.\n");
  556.  if ((polyvertex->ptype)==0)
  557.   fprintf(fout,"OFF\n %d %d 1\n",polyvertex->numvtx,polyhedron->numpoly);
  558.  else
  559.   fprintf(fout,"COFF\n %d %d 1\n",polyvertex->numvtx,polyhedron->numpoly);
  560.  polyvertex->write_vertices(fout);
  561.  polyhedron->write_polys(fout);
  562.  fclose(fout);
  563.  
  564. }
  565.  
  566. /*****************************************************************************/
  567.  
  568. void main_clip(int argc, char *argv[])
  569. {
  570.   poly_list polyhedron;
  571.   vertex_list polyvertex;
  572.   char *storename = new char[256];
  573.  
  574.   load_off_file(&polyhedron,&polyvertex,argc,argv,storename);
  575.   polyvertex.clip_vertex(argc,argv);
  576.   polyhedron.clip_polys(&polyvertex);
  577.   polyvertex.refresh_vertex_list();
  578.   polyhedron.refresh_poly_list();
  579.   store_off_file(&polyhedron,&polyvertex,storename);
  580. }
  581. /*****************************************************************************/
  582.